Skip to content

Select default emulator on first run#217

Merged
anisaoshafi merged 22 commits intomainfrom
drg-381-add-option-to-select-default-emulator
May 7, 2026
Merged

Select default emulator on first run#217
anisaoshafi merged 22 commits intomainfrom
drg-381-add-option-to-select-default-emulator

Conversation

@anisaoshafi
Copy link
Copy Markdown
Contributor

@anisaoshafi anisaoshafi commented Apr 30, 2026

First-time users are prompted to choose their emulator (AWS or Snowflake) before lstk starts (to simulate this, rename or delete config.toml). The choice is saved to the config file immediately.

  • When run with --non-interactive / no TTY it silently uses the AWS by default.
Screenshot 2026-04-30 at 16 59 20 Note to user they can change to the other emulator: Screenshot 2026-04-30 at 16 59 43

@anisaoshafi anisaoshafi force-pushed the drg-381-add-option-to-select-default-emulator branch 17 times, most recently from e1db26a to 4204284 Compare May 4, 2026 15:34
@anisaoshafi anisaoshafi marked this pull request as ready for review May 4, 2026 15:39
@anisaoshafi anisaoshafi requested a review from gtsiolis May 4, 2026 15:39
@carole-lavillonniere
Copy link
Copy Markdown
Collaborator

@anisaoshafi @gtsiolis it feels a bit odd to me that the --emulator flag overwrites the config. The convention for flags as far as I know is to be transient/ephemeral.

Users can still manually edit their config if they want to.

If we want to provide a way to reset the emulator in the config from command line, what about something like lstk start --reset-config or lstk config emulator that would prompt again Which emulator would you like to use?

lstk start --emulator <type> could override the config, but only temporarily.

@anisaoshafi
Copy link
Copy Markdown
Contributor Author

@anisaoshafi @gtsiolis it feels a bit odd to me that the --emulator flag overwrites the config. The convention for flags as far as I know is to be transient/ephemeral.

Users can still manually edit their config if they want to.

If we want to provide a way to reset the emulator in the config from command line, what about something like lstk start --reset-config or lstk config emulator that would prompt again Which emulator would you like to use?

lstk start --emulator <type> could override the config, but only temporarily.

Good point, can be too much of a responsibility for a flag.

I like lstk config emulator option. Does the same but in a more controlled way since the user have to confirm the option, or cancel if that's not what they intended.
Will wait for @gtsiolis's opinion before making the changes 🙏🏼

@carole-lavillonniere
Copy link
Copy Markdown
Collaborator

@anisaoshafi @gtsiolis it feels a bit odd to me that the --emulator flag overwrites the config. The convention for flags as far as I know is to be transient/ephemeral.
Users can still manually edit their config if they want to.
If we want to provide a way to reset the emulator in the config from command line, what about something like lstk start --reset-config or lstk config emulator that would prompt again Which emulator would you like to use?
lstk start --emulator <type> could override the config, but only temporarily.

Good point, can be too much of a responsibility for a flag.

I like lstk config emulator option. Does the same but in a more controlled way since the user have to confirm the option, or cancel if that's not what they intended. Will wait for @gtsiolis's opinion before making the changes 🙏🏼

If we decide for another command, I think we can leave it out of the scope of this PR/create another issue for it to keep this PR small.

Comment thread internal/config/switch.go Outdated
Comment thread cmd/root.go Outdated
Comment thread internal/config/switch.go Outdated
Comment thread internal/config/switch.go Outdated
Comment thread test/integration/emulator_select_test.go Outdated
Comment thread cmd/root.go Outdated
Comment thread cmd/root.go Outdated
Comment thread internal/config/switch.go Outdated
tag = "latest"
port = "4566"
# volume = "" # Host directory for persistent state (default: OS cache dir)
# env = [] # Named environment profiles to apply (see [env.*] sections below)`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question:
At the moment those blocks are duplicated and there is a chance of drift.
How hard it is to parse those blocks from default_config.toml?
Another solution could be to use go templates in default_config.toml so the container blocks could come from another file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed here 🙏🏼 0aeca91

Comment thread internal/config/emulator_type_test.go
Comment thread cmd/root.go Outdated
@anisaoshafi anisaoshafi marked this pull request as draft May 5, 2026 11:24
@gtsiolis
Copy link
Copy Markdown
Member

gtsiolis commented May 5, 2026

Looking at this now! 👀

@anisaoshafi anisaoshafi force-pushed the drg-381-add-option-to-select-default-emulator branch from ada0134 to 5e7723a Compare May 5, 2026 12:34
Comment thread internal/config/switch.go Outdated
Comment on lines +18 to +20
type = "snowflake"
tag = "latest"
port = "4566"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Similar to what @carole-lavillonniere mentioned above, this leads to content duplication.

# [[containers]]
# type = "aws"     # Emulator type. Currently supported: "aws", "snowflake"
# tag  = "latest"  # Docker image tag, e.g. "latest", "2026.03"
# port = "4566"    # Host port the emulator will be accessible on
# # volume = ""    # Host directory for persistent state (default: OS cache dir)
# # env = []       # Named environment profiles to apply (see [env.*] sections below)

[...]

[[containers]]
type = "snowflake"
tag  = "latest"
port = "4566"
# volume = ""    # Host directory for persistent state (default: OS cache dir)
# env = []       # Named environment profiles to apply (see [env.*] sections below)

I'd expect if I select SNO on start, to simply use snowflake in the first [[containers]] section.

[...]
[[containers]]
type = "snowflake"     # Emulator type. Currently supported: "aws", "snowflake"
tag  = "latest"  # Docker image tag, e.g. "latest", "2026.03"
port = "4566"    # Host port the emulator will be accessible on
volume = ""    # Host directory for persistent state (default: OS cache dir)
env = []       # Named environment profiles to apply (see [env.*] sections below)
[...]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to tackle this 💯

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed here 🙏🏼 0aeca91

Comment thread internal/ui/run.go Outdated
Comment thread internal/ui/run.go Outdated
Comment thread internal/ui/run.go Outdated
Prompt: "Which emulator would you like to use?",
Options: []output.InputOption{
{Key: "a", Label: "AWS [A]"},
{Key: "s", Label: "Snowflake [S]"},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue(non-blocking): Here's what most users with no access to SNO emulation will see. I guess this comes from the emulator, right? Could we mask now or later this error?

Image

SNO users in trial see no error currently.

Have to check what SNO-only users in production see.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, comes from emulator side. I created a follow up task: DRG-818 for handling this error in a nicer way since it's out of the scope for this PR 🙏🏼

Comment thread internal/ui/run.go Outdated

msg := selected.DisplayName() + " emulator selected."
if configPath != "" {
msg += fmt.Sprintf(" You can change this anytime in %s.", configPath)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The message here wraps early on line 2, can we make the message wrap normally in two lines, I think we do so for other messages, right?

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gtsiolis Does this look a bit better? Also changed the message as you proposed in the other comment image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of using the same success message as the AWS profile creation? This will avoid ending up with multiple NOTE messages when the emulator is running (although edge case) and make the output more functional upon selection.

1/2 2/2
Screenshot 2026-05-05 at 20.56.01.png Screenshot 2026-05-05 at 20.56.03.png

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same success message as the AWS profile creation

What does this mean when the user selects snowflake on first try?

@gtsiolis sorry, I'm not following. Can you rephrase your suggestion?
Did you mean Change configuration in ~/.config/lstk/config.toml should have a green tick in front?

Comment thread internal/ui/run.go Outdated
labelCh <- label
}

func selectEmulatorInTUI(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Thanks for reusing this UX!

@anisaoshafi anisaoshafi marked this pull request as ready for review May 6, 2026 12:00
Comment thread internal/ui/run.go Outdated

return newCfg.Containers, nil
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: now I think we should just move selectEmulatorInTUI and resolveAndCacheLabel out of internal/ui and we should be good. These are domain code.

AGENTS.md is kind of documenting this with:

  • Do not pass UI callbacks like onProgress func(...) through domain layers; prefer typed output events.
  1. Keep UI as presentation/orchestration only; business logic stays in domain packages.

domain packages => everything under internal/ except internal/ui/.
A test for "is this domain code?": if we wired a different kind of frontend, domain code should still work.

AGENTS.md does not explicitly say where the code executed upon user input lives, though. I think it'd be good to add a line about this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attempted to address here: fe93529

return name
}
return string(e)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: we already have DisplayNameForType line 77.
Can we

  • refactor to make them one?
  • or rename to make more explicit?
  • and/or change the signatures so that they are both methods?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried here: 62926ca

Comment thread internal/ui/run.go Outdated
Prompt: "Which emulator would you like to use?",
Options: []output.InputOption{
{Key: "a", Label: "AWS"},
{Key: "s", Label: "Snowflake"},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: possible to build the options from emulatorDisplayNames or another map, to make it more dynamic?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried here: b4fc4cf

Comment thread cmd/root.go
}
*firstRun, err = config.Init()
return err
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: do we really need 2 functions initConfig and initConfigCapturingFirstRun? They look quite similar

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, tried here: 6ced3fe


cancel()
<-outputCh
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: what about completing this test with an actual user input, making sure we persist the choice in the config and start that chosen emulator?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: we could also add a simple test to make sure we don't prompt when the config is already created?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point: tried here and here 🙏🏼

@anisaoshafi anisaoshafi force-pushed the drg-381-add-option-to-select-default-emulator branch from f4d7f78 to 3d88700 Compare May 7, 2026 11:07
Copy link
Copy Markdown
Collaborator

@carole-lavillonniere carole-lavillonniere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳

@anisaoshafi anisaoshafi merged commit bf72a00 into main May 7, 2026
12 checks passed
@anisaoshafi anisaoshafi deleted the drg-381-add-option-to-select-default-emulator branch May 7, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants